package com.mano.mall.service.callback.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.internal.util.StringUtils;
import com.mano.commons.web.utils.HttpRequestUtil;
import com.mano.mall.plugin.pay.ali.config.AlipayConfig;
import com.mano.mall.plugin.pay.union.sdk.LogUtil;
import com.mano.mall.service.callback.template.AbstractPayCallbackTemplate;
import com.mano.mall.service.constant.PayConstant;
import com.mano.mall.service.mapper.PaymentTransactionMapper;
import com.mano.mall.service.mapper.entity.PaymentTransactionEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @Author: zj
 * @Description:支付宝回调通知
 * @Date: Created in 9:31 2020/10/29
 * @Modified By:
 */
@Component
public class AliPayCallbackTemplate extends AbstractPayCallbackTemplate {
    @Autowired
    private PaymentTransactionMapper paymentTransactionMapper;

    @Override
    public Map<String, String> verifySignature(HttpServletRequest req, HttpServletResponse resp) {
        LogUtil.writeLog("BackRcvResponse接收支付宝后台通知开始");
        Map<String, String> reqParam = HttpRequestUtil.getAllRequestParam(req);

        try {
            // 调用支付的sdk的接口校验
            boolean sign = AlipaySignature.rsaCheckV2(reqParam, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
            if(!sign){
                LogUtil.writeLog("支付宝回调参数校验失败");
                reqParam.put(PayConstant.RESULT_NAME, PayConstant.RESULT_PAYCODE_201);
            }else{
                LogUtil.writeLog("支付宝回调参数校验成功");
                //参数校验
                if(StringUtils.isEmpty(reqParam.get("total_amount"))
                        || StringUtils.isEmpty(reqParam.get("out_trade_no"))
                        || StringUtils.isEmpty(reqParam.get("trade_no"))
                        || StringUtils.isEmpty(reqParam.get("trade_status"))){
                    reqParam.put(PayConstant.RESULT_NAME, PayConstant.RESULT_PAYCODE_201);
                }else{
                    // out_trade_no  原支付请求的商户订单号
                    String orderId = reqParam.get("out_trade_no"); // 获取后台通知的数据，其他字段也可用类似方式获取
                    reqParam.put("paymentId", orderId);
                    reqParam.put(PayConstant.RESULT_NAME, PayConstant.RESULT_PAYCODE_200);
                }

            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        LogUtil.writeLog("BackRcvResponse接收支付宝后台通知结束");

        return reqParam;
    }

    @Override
    public String asyncService(Map<String, String> verifySignature) {
        String orderId = verifySignature.get("orderId"); // 获取后台通知的数据，其他字段也可用类似方式获取
        String respCode = verifySignature.get("trade_status");

        System.out.println("orderId:" + orderId + ",respCode:" + respCode);

        if (!(respCode.equals("TRADE_SUCCESS") || respCode.equals("TRADE_FINISHED"))) {
            return failResult();
        }
        // 根据日志 手动补偿 使用支付id调用第三方支付接口查询
        PaymentTransactionEntity paymentTransaction = paymentTransactionMapper.selectByPaymentId(orderId);
        if (paymentTransaction.getPaymentStatus().equals(PayConstant.PAY_STATUS_SUCCESS)) {
            // 网络重试中，之前已经支付过
            return successResult();
        }
        // 2.将状态改为已经支付成功
        paymentTransactionMapper.updatePaymentStatus(PayConstant.PAY_STATUS_SUCCESS + "", orderId,PayConstant.ALI_PAY_CHANNEL);
        // 3.调用积分服务接口增加积分(处理幂等性问题)
        return successResult();
    }

    @Override
    public String failResult() {
        return PayConstant.ALI_RESULT_SUCCESS;
    }

    @Override
    public String successResult() {
        return PayConstant.ALI_RESULT_SUCCESS;
    }

}
